package work.timejay.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FastByteArrayOutputStream;
import cn.hutool.core.util.HashUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import work.timejay.config.MinioConfig;
import work.timejay.constants.DateConstants;
import work.timejay.exception.TimeJayException;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;

/**
 * @className:FileUtils.java
 * @author:王文杰
 * @version:1.0.0
 * @description:文件上传下载工具类
 * @createTime 2023年11月23日 16:14:00
 */
@Component
@Slf4j
public class FileUtils {

    private static final String SPLICING_POINT = ".";

    private static final String SPLICING_ACROSS = "-";

    @Autowired
    private MinioConfig minioConfig;

    @Autowired
    private MinioClient minioClient;

    public Boolean existsBucket(String bucketName) {
        try {
            boolean existsBucket = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!existsBucket) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
                return true;
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            throw TimeJayException.fail("500", "minioBucket上传异常");
        }
    }


    /**
     * 文件上传
     */
    public String upload(MultipartFile file) {
        try {
            String originalFilename = file.getOriginalFilename();
            if (StringUtils.isBlank(originalFilename)) {
                throw new RuntimeException();
            }
            existsBucket(minioConfig.getBucketName());
            String suffixName = originalFilename.substring(originalFilename.lastIndexOf(SPLICING_POINT));
            String fileName = originalFilename.substring(0, originalFilename.lastIndexOf(SPLICING_POINT));
            String targetFileName = DateUtil.format(new Date(), DateConstants.DATE_YYYY_MM_DD_HH_MM_SS_FORMAT) + SPLICING_ACROSS + fileName + suffixName;
           //            String targetFileName =System.currentTimeMillis() + SecureUtil.md5(fileName)+ suffixName;
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .object(targetFileName)
                    .stream(file.getInputStream(), file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build();
            minioClient.putObject(putObjectArgs);
            return targetFileName;
        } catch (Exception e) {
            e.printStackTrace();
            throw TimeJayException.fail("500", "minioUpload上传异常");
        }
    }

    /**
     * 文件上传
     */
    public String upload(byte[] file,String filename,String suffix) {
        InputStream input = new ByteArrayInputStream(file);
        try {
            if (StringUtils.isBlank(filename)) {
                throw new RuntimeException();
            }
            String targetFileName = filename+suffix;
            existsBucket(minioConfig.getBucketName());
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .bucket(minioConfig.getBucketName())
                    .object(targetFileName)
                    .stream(input, input.available(), -1)
                    .build();
            minioClient.putObject(putObjectArgs);
            return targetFileName;
        } catch (Exception e) {
            e.printStackTrace();
            throw TimeJayException.fail("500", "minioUpload上传异常");
        }
    }

    /**
     * 预览图片
     *
     * @param fileName
     * @return
     */
    public String preview(String fileName) {
        // 查看文件地址
        GetPresignedObjectUrlArgs build = GetPresignedObjectUrlArgs.builder()
                .bucket(minioConfig.getBucketName())
                .object(fileName)
                .method(Method.GET)
                .build();
        try {
            return minioClient.getPresignedObjectUrl(build);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 文件下载
     *
     * @param fileName 文件名称
     * @param res      response
     * @return Boolean
     */
    public void download(String fileName, HttpServletResponse res) {
        GetObjectArgs objectArgs = GetObjectArgs.builder()
                .bucket(minioConfig.getBucketName())
                .object(fileName)
                .build();
        try (GetObjectResponse response = minioClient.getObject(objectArgs)) {
            byte[] buf = new byte[1024];
            int len;
            try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()) {
                while ((len = response.read(buf)) != -1) {
                    os.write(buf, 0, len);
                }
                os.flush();
                byte[] bytes = os.toByteArray();
                res.setCharacterEncoding("utf-8");
                // 设置强制下载不打开
                // res.setContentType("application/force-download");
                res.addHeader("Content-Disposition", "attachment;fileName=" + fileName);
                try (ServletOutputStream stream = res.getOutputStream()) {
                    stream.write(bytes);
                    stream.flush();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args)
            throws IOException, NoSuchAlgorithmException, InvalidKeyException {
        try {
            // Create a minioClient with the MinIO server playground, its access key and secret key.
            MinioClient minioClient =
                    MinioClient.builder()
                            .endpoint("http://106.55.226.208:9000")
                            .credentials("Fc9oXx4WyBHuQc7nSmJR", "198mpaqJVBY32Nckq0hd9GsVDdzR4TxSw6p51uQr")
                            .build();

            // 判断bucket桶是否存在，不存在创建一个
            boolean found =
                    minioClient.bucketExists(BucketExistsArgs.builder().bucket("timejay").build());
            if (!found) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket("timejay").build());
            } else {
                System.out.println("bucket桶timejay存在");
            }

            // Upload '/home/user/Photos/asiaphotos.zip' as object name 'asiaphotos-2015.zip' to bucket
            // 'asiatrip'.
            minioClient.uploadObject(
                    UploadObjectArgs.builder()
                            .bucket("timejay")
                            .object("test.jpg")
                            .filename("C:\\Users\\Administrator\\Desktop\\t\\Snipaste_2023-05-11_09-44-15.jpg")
                            .build());
        } catch (MinioException e) {
            System.out.println("Error occurred: " + e);
            System.out.println("HTTP trace: " + e.httpTrace());
        }
    }
}
